package com.feiyisys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feiyisys.dto.ActivityAuditDTO;
import com.feiyisys.dto.ActivityRegistrationDTO;
import com.feiyisys.dto.ActivityRegistrationResponseDTO;
import com.feiyisys.entity.Activity;
import com.feiyisys.entity.ActivityRegistration;
import com.feiyisys.mapper.ActivityMapper;
import com.feiyisys.mapper.ActivityRegistrationMapper;
import com.feiyisys.service.ActivityRegistrationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import jakarta.annotation.Resource;
import java.util.Date;

/**
 * <p>
 * 活动报名表 服务实现类
 * </p>
 *
 * @author
 * @since 2025-10-10
 */
@Service
public class ActivityRegistrationServiceImpl extends ServiceImpl<ActivityRegistrationMapper, ActivityRegistration> implements ActivityRegistrationService {

    @Resource
    private ActivityMapper activityMapper;

    @Override
    @Transactional
    public ActivityRegistrationResponseDTO registerActivity(Long userId, ActivityRegistrationDTO registrationDTO) {
        // 验证活动信息
        Activity activity = activityMapper.selectById(registrationDTO.getActivityId());
        Assert.notNull(activity, "活动不存在");
        Assert.isTrue(activity.getStatus() == 1, "活动当前不可报名");

        // 检查重复报名
        LambdaQueryWrapper<ActivityRegistration> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ActivityRegistration::getActivityId, registrationDTO.getActivityId())
                .eq(ActivityRegistration::getUserId, userId);
        ActivityRegistration existing = this.getOne(wrapper);
        Assert.isNull(existing, "您已报名该活动");

        // 创建报名记录
        ActivityRegistration registration = new ActivityRegistration();
        registration.setActivityId(registrationDTO.getActivityId());
        registration.setUserId(userId);
        registration.setRealName(registrationDTO.getRealName());
        registration.setPhone(registrationDTO.getPhone());
        registration.setEmail(registrationDTO.getEmail());
        registration.setStatus((byte) 0); // 待审核
        registration.setCreateTime(new Date());
        registration.setUpdateTime(new Date());

        this.save(registration);

        // 更新活动的当前参与人数
        activity.setCurrentParticipants((activity.getCurrentParticipants() != null ? activity.getCurrentParticipants() : 0) + 1);
        activityMapper.updateById(activity);

        return buildResponseDTO(registration, activity);
    }

    @Override
    @Transactional
    public boolean auditActivityRegistration(ActivityAuditDTO auditDTO) {
        // 查询并验证报名记录
        ActivityRegistration registration = this.getById(auditDTO.getId());
        Assert.notNull(registration, "报名记录不存在");
        Assert.isTrue(registration.getStatus() == 0, "该记录已审核，请勿重复操作");

        // 更新审核状态
        registration.setStatus(auditDTO.getStatus());
        Date now = new Date();
        registration.setAuditTime(now);
        registration.setUpdateTime(now);

        // 处理审核结果
        if (auditDTO.getStatus() == 2) { // 审核拒绝
            Assert.hasLength(auditDTO.getAuditRemark(), "拒绝原因不能为空");
            Assert.isTrue(auditDTO.getAuditRemark().length() <= 10, "拒绝原因不能超过10个字");
            registration.setAuditRemark(auditDTO.getAuditRemark());

            // 审核拒绝时，减少活动的当前参与人数
            Activity activity = activityMapper.selectById(registration.getActivityId());
            if (activity != null && activity.getCurrentParticipants() != null && activity.getCurrentParticipants() > 0) {
                activity.setCurrentParticipants(activity.getCurrentParticipants() - 1);
                activityMapper.updateById(activity);
            }
        } else {
            registration.setAuditRemark(null);
        }

        return this.updateById(registration);
    }

    @Override
    public IPage<ActivityRegistrationResponseDTO> getPendingRegistrations(Long current, Long size) {
        return getRegistrations(null, (byte) 0, current, size);
    }

    @Override
    public ActivityRegistrationResponseDTO getRegistrationDetail(Long id) {
        ActivityRegistration registration = this.getById(id);
        if (registration == null) {
            return null;
        }

        Activity activity = activityMapper.selectById(registration.getActivityId());
        return buildResponseDTO(registration, activity);
    }

    @Override
    public IPage<ActivityRegistrationResponseDTO> getRegistrations(Long activityId, Byte status, Long current, Long size) {
        Page<ActivityRegistration> page = new Page<>(current, size);
        LambdaQueryWrapper<ActivityRegistration> wrapper = new LambdaQueryWrapper<>();
        if (activityId != null) {
            wrapper.eq(ActivityRegistration::getActivityId, activityId);
        }
        if (status != null) {
            wrapper.eq(ActivityRegistration::getStatus, status);
        }
        wrapper.orderByDesc(ActivityRegistration::getCreateTime);

        IPage<ActivityRegistration> registrationPage = this.page(page, wrapper);
        return registrationPage.convert(registration -> {
            Activity activity = activityMapper.selectById(registration.getActivityId());
            return buildResponseDTO(registration, activity);
        });
    }

    @Override
    public String generateRegistrationNo() {
        return "REG" + System.currentTimeMillis();
    }

    @Override
    public IPage<ActivityRegistrationResponseDTO> getRegistrationsByActivityId(Long activityId, Long current, Long size) {
        return getRegistrations(activityId, null, current, size);
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(Byte status) {

        switch (status) {
            case 0: return "待审核";
            case 1: return "已通过";
            case 2: return "已拒绝";
            default: return "未知状态";
        }
    }

    private ActivityRegistrationResponseDTO buildResponseDTO(ActivityRegistration registration, Activity activity) {
        ActivityRegistrationResponseDTO dto = new ActivityRegistrationResponseDTO();
        dto.setId(registration.getId());
        dto.setActivityId(registration.getActivityId());
        if (activity != null) {
            dto.setActivityTitle(activity.getTitle());
        }
        dto.setRealName(registration.getRealName());
        dto.setPhone(registration.getPhone());
        dto.setEmail(registration.getEmail());
        dto.setStatus(registration.getStatus());
        dto.setStatusText(getStatusText(registration.getStatus()));
        dto.setAuditRemark(registration.getAuditRemark());
        dto.setCreateTime(registration.getCreateTime());
        dto.setAuditTime(registration.getAuditTime());
        dto.setRegistrationNo(formatRegistrationNo(registration.getId()));
        return dto;
    }

    private String formatRegistrationNo(Long id) {
        if (id == null) {
            return generateRegistrationNo();
        }
        return "REG" + String.format("%010d", id);
    }
}
